<?php

namespace App\Service;
use App\Model\Contract;
use Hyperf\Utils\Arr;

class OpenSearch
{
    const SDK_VERSION = '3.3.0';
    const METHOD_GET = 'GET';
    public $connectTimeout = 1;
    public $timeout = 3;
    public $gzip = false;
    private $debug = false;

    public function bulk($data)
    {
        $uri = "/apps/souhetong/db_sou_hetong/actions/bulk";
        $accessKeyId = "LTAI5tCMFtVBctspxvSLVjgm";
        $secret = "9t5sM7TkxUPAxSvUS3Q1QdoHiXJAIM";
        $path = "/v3/openapi{$uri}";
        $url = "http://opensearch-cn-hangzhou.aliyuncs.com". $path;
        // $url = "http://opensearch-cn-shenzhen.aliyuncs.com". $path;
        $body = json_encode($data,true);
        $search = new OpenSearch();
        $items = array();
        $items['method'] = 'POST';
        $items['request_path'] = $path;
        $items['content_type'] = "application/json";
        $items['accept_language'] = "zh-cn";
        $items['date'] = gmdate('Y-m-d\TH:i:s\Z');
        $items['opensearch_headers'] = array();
        $items['content_md5'] = "";
        $items['opensearch_headers']['X-Opensearch-Nonce'] = $search->_nonce();
        if (!empty($body)) {
            $items['content_md5'] = md5($body);
            $items['body_json'] = $body;
        }
        $signature = $search->_signature($secret, $items);
        $items['authorization'] = "OPENSEARCH {$accessKeyId}:{$signature}";

        $data = json_decode(json_encode($search->_curl($url, $items)),true);
        $json = json_decode($data,true);
        return ['data'=>$json];

    }

    public function _curl($url, $items) {
        $guzzleClient = new Client();
        $method = strtoupper($items['method']);
        $options = array(
            CURLOPT_HTTP_VERSION => 'CURL_HTTP_VERSION_1_1',
            CURLOPT_CONNECTTIMEOUT => $this->connectTimeout,
            CURLOPT_TIMEOUT => $this->timeout,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HEADER => false,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERAGENT => "opensearch/php sdk " . self::SDK_VERSION . "/" . PHP_VERSION,
            CURLOPT_HTTPHEADER => $this->_getHeaders($items),
        );
        $headers = [
            'Content-Type' =>  $this->_getHeaders($items),
            // 添加其他请求头部...
        ];

        if ($method == self::METHOD_GET) {
            $query = Arr::query($items['query_params']);
            $url .= preg_match('/\?/i', $url) ? '&' . $query : '?' . $query;
        } else{
            if(!empty($items['body_json'])){
                $options[CURLOPT_POSTFIELDS] = $items['body_json'];
            }
        }
        if ($this->gzip) {
            $options[CURLOPT_ENCODING] = 'gzip';
        }

        if ($this->debug) {
            $out = fopen('php://temp','rw');
            $options[CURLOPT_VERBOSE] = true;
            $options[CURLOPT_STDERR] = $out;
        }
        $session = curl_init($url);
        curl_setopt_array($session, $options);
        $response = curl_exec($session);
        curl_close($session);
        return $response;
    }

    public function _buildQuery($params) {
//        $query = '';
//        if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
//
//            $query = !empty($params) ? http_build_query($params, null, '&', PHP_QUERY_RFC3986) : '';
//        } else {
//            $arg = '';
//            foreach ($params as $key => $val) {
//                $arg .= rawurlencode($key) . "=" . rawurlencode($val) . "&";
//            }
//            $query = substr($arg, 0, count($arg) - 2);
//        }
        return Arr::query($params);

    }

    public function _nonce() {
        return intval(microtime(true) * 1000) . mt_rand(10000, 99999);
    }

    public function _signature($secret, $items) {
        $params = isset($items['query_params']) ? $items['query_params'] : "";

        $signature = '';
        $string = '';
        $string .= strtoupper($items['method']) . "\n";
        $string .= $items['content_md5'] . "\n";
        $string .= $items['content_type'] . "\n";
        $string .= $items['date'] . "\n";

        $headers = self::_filter($items['opensearch_headers']);
        foreach($headers as $key => $value){
            $string .= strtolower($key) . ":" . $value."\n";
        }
        $resource = str_replace('%2F', '/', rawurlencode($items['request_path']));
        $sortParams = self::_filter($params);
        $queryString =  Arr::query($sortParams);
        $canonicalizedResource = $resource;

        if(!empty($queryString)){
            $canonicalizedResource .= '?'.$queryString;
        }
        $string .= $canonicalizedResource;
        $signature = base64_encode(hash_hmac('sha1', $string, $secret, true));
        return $signature;
    }

    private function _filter($parameters = array()){
        $params = array();
        if(!empty($parameters)){
            foreach ($parameters as $key => $val) {
                if ($key == "Signature" ||$val === "" || $val === NULL){
                    continue;
                } else {
                    $params[$key] = $parameters[$key];
                }
            }

            uksort($params,'strnatcasecmp');
            reset($params);
        }
        return $params;
    }


    private function _getHeaders($items) {
        $headers = array();
        $headers[] = 'Content-Type: '.$items['content_type'];
        $headers[] = 'Date: '.$items['date'];
        $headers[] = 'Accept-Language: '.$items['accept_language'];
        $headers[] = 'Content-Md5: '.$items['content_md5'];
        $headers[] = 'Authorization: '.$items['authorization'];
        if (is_array($items['opensearch_headers'])) {
            foreach($items['opensearch_headers'] as $key => $value){
                $headers[] = $key . ": " . $value;
            }
        }

        return $headers;
    }

    /**下拉提示
     * @param $data
     * @return mixed
     */
    public function sugguest($data){
        $uri="/apps/souhetong/suggest/sugguest/search";
        $accessKeyId = "LTAI5tCMFtVBctspxvSLVjgm";
        $secret = "9t5sM7TkxUPAxSvUS3Q1QdoHiXJAIM";
        $params=[
            'query' => $data,
//            'query' => "config=start:".$page.", hit:".$limit.",format:fulljson&&query=default:'".$keyword."'",
//            'first_rank_name' => 'test',
            'hit' => 10
        ];
        $path = "/v3/openapi{$uri}";
        $url = "http://opensearch-cn-hangzhou.aliyuncs.com". $path;
        //    $url = "http://opensearch-cn-shanghai.aliyuncs.com". $path;
        $body = "";
        $items = array();
        $items['method'] = 'GET';
        $items['request_path'] = $path;
        $items['content_type'] = "application/json";
        $items['accept_language'] = "zh-cn";
        $items['date'] = gmdate('Y-m-d\TH:i:s\Z');
        $items['opensearch_headers'] = array();
        $items['content_md5'] = "";
        $items['opensearch_headers']['X-Opensearch-Nonce'] = $this->_nonce();
        if (!empty($body)) {
            $items['content_md5'] = md5($body);
            $items['body_json'] = $body;
        }

        $items['query_params'] = $params;

        $signature = $this->_signature($secret, $items);
        $items['authorization'] = "OPENSEARCH {$accessKeyId}:{$signature}";

        $data = json_decode(json_encode($this->_curl($url, $items)),true);
        $json = json_decode($data,true);
        return $json;
    }

    /**opensearch搜索
     * @param array $data
     * @return array
     */
    public function index(array $data)
    {

        $uri="/apps/souhetong/search";

        // $uri = "/apps/souhetong/souhetong/actions/bulk";


        $accessKeyId = "LTAI5tCMFtVBctspxvSLVjgm";
        $secret = "9t5sM7TkxUPAxSvUS3Q1QdoHiXJAIM";

        $keyword = $data['keyword'];
        $page =  $data['page'] ?? 1;
        $limit =  $data['limit'] ?? 20;
        $order = $data['order']??'normal';


        //$uri, array $params, $body, $method)
        if($page == 1){
            $page = 0;
        } else {
            $page = (int)($page-1) * (int)$limit;
        }
        $params=[
            'fetch_fields' => 'title;id',
            'query' => "config=start:".$page.", hit:".$limit.",format:fulljson&&query=default:'".$keyword."'",
            'first_rank_name' => 'test',
            'num' => '20'
        ];




        $path = "/v3/openapi{$uri}";
        $url = "http://opensearch-cn-hangzhou.aliyuncs.com". $path;
        //    $url = "http://opensearch-cn-shanghai.aliyuncs.com". $path;
        $body = "";
        $items = array();
        $items['method'] = 'GET';
        $items['request_path'] = $path;
        $items['content_type'] = "application/json";
        $items['accept_language'] = "zh-cn";
        $items['date'] = gmdate('Y-m-d\TH:i:s\Z');
        $items['opensearch_headers'] = array();
        $items['content_md5'] = "";
        $items['opensearch_headers']['X-Opensearch-Nonce'] = $this->_nonce();
        if (!empty($body)) {
            $items['content_md5'] = md5($body);
            $items['body_json'] = $body;
        }

        $items['query_params'] = $params;
        $signature = $this->_signature($secret, $items);
        $items['authorization'] = "OPENSEARCH {$accessKeyId}:{$signature}";
        $data = json_decode(json_encode($this->_curl($url, $items)),true);
        $json = json_decode($data,true);
        if(!is_null($json) && $json['result']['total'] > 0){
            $fields =  array_column($json['result']['items'], 'fields');
            $id = array_column($fields,'id');
            switch ($order){
                case 'time':
                    $result = Contract::whereIn('id',$id)
                        ->where('is_finish',1)
                        ->select('id','title','title_pic','download')
                        ->orderBy('id','desc')
                        ->get();
                    break;
                case 'download':
                    $result = Contract::whereIn('id',$id)
                        ->where('is_finish',1)
                        ->select('id','title','title_pic','download')
                        ->orderBy('download','desc')
                        ->get();
                    break;
                default:
                    $result = Contract::whereIn('id',$id)
                        ->where('is_finish',1)
                        ->select('id','title','title_pic','download')
                        ->orderBy(\DB::raw('FIND_IN_SET(id, "' . implode(",", $id) . '"' . ")"))
                        ->get();

            }
        }else{
            $result = '';
        }
        var_dump(3);
        return [
            'code' => 200,
            'msg' => '请求成功',
            'data'=> $result,
//                'per_page' =>$limit,
//                'current_page' => $page,
            'total' => $json['result']['total']>5000?5000:$json['result']['total'],
//                'last_page' => ceil((int)$json['result']['total'] / (int)$limit )
        ];

    }
}
